#include <iostream>
#include <SDL/SDL.h>

#if 0
#include "mandelbrot.hh"
#include "julia.hh"

#include "perlin.hh"
#include "revert.hh"
#include "grayscale.hh"
#include "bin.hh"
#include "binary_or.hh"
#include "convolution.hh"
#endif

#include "tbb/task_scheduler_init.h"
#include "tbb/parallel_for.h"
#include "tbb/blocked_range2d.h"

#include "common.hh"
#include "shell.hh"

SDL_Surface* global_screen;

int main (int argc, char* argv[])
{
  SDL_Surface* affichage;
  SDL_Event event;
  Uint32	**img1, **img2;
  int		**mat;
  argc = argc;
  argv = argv;

  #if 0
  tbb::task_scheduler_init    init;

  init.initialize (4);
  #endif

  if (SDL_Init(SDL_INIT_VIDEO) < 0)
    {
      std::cout << "could not initialize SDL" << std::endl;
      return 1;
    }

  #if 0
  mat = (int **)malloc(3 * sizeof (int*));
  for (unsigned i = 0; i < 3; ++i)
    {
      mat[i] = (int *)malloc(3 * sizeof (int));
      mat[i][0] = 1;
      mat[i][1] = 1;
      mat[i][2] = 1;
    }

  img1 = (Uint32 **)malloc(HEIGHT * sizeof (Uint32*));
  img2 = (Uint32 **)malloc(HEIGHT * sizeof (Uint32*));
  for (unsigned i = 0 ; i < HEIGHT; ++i)
    {
      img1[i] = (Uint32 *)malloc (WIDTH * sizeof (Uint32));
      img2[i] = (Uint32 *)malloc (WIDTH * sizeof (Uint32));
    }
  #endif

  affichage = SDL_SetVideoMode(WIDTH, HEIGHT, 32, SDL_SWSURFACE);
  global_screen = affichage;

  SDL_WM_SetCaption("PrPa", NULL);

  #if 0
  tbb::tick_count t0 = tbb::tick_count::now();
  tbb::parallel_for(tbb::blocked_range2d<int>(0,HEIGHT, 0,WIDTH),
  		    MandelbrotParrallel(img1, affichage->format), tbb::auto_partitioner());
  tbb::tick_count t1 = tbb::tick_count::now();
  std::cout << "// : " << (t1 - t0).seconds() << "s" << std::endl;

  t0 = tbb::tick_count::now();
  tbb::parallel_for(tbb::blocked_range2d<int>(0,HEIGHT, 0,WIDTH),
  		    JuliaParrallel(img2, affichage->format), tbb::auto_partitioner());
  t1 = tbb::tick_count::now();
  std::cout << "Julia // : " << (t1 - t0).seconds() << "s" << std::endl;

  t0 = tbb::tick_count::now();
  tbb::parallel_for(tbb::blocked_range2d<int>(0,HEIGHT, 0,WIDTH),
  		    Revert(img1, affichage->format), tbb::auto_partitioner());
  t1 = tbb::tick_count::now();
  std::cout << "revert // : " << (t1 - t0).seconds() << "s" << std::endl;

  t0 = tbb::tick_count::now();
  tbb::parallel_for(tbb::blocked_range2d<int>(0,HEIGHT, 0,WIDTH),
  		    GrayScale(img1, affichage->format), tbb::auto_partitioner());
  t1 = tbb::tick_count::now();
  std::cout << "gray // : " << (t1 - t0).seconds() << "s" << std::endl;

  t0 = tbb::tick_count::now();
  tbb::parallel_for(tbb::blocked_range2d<int>(0,HEIGHT, 0,WIDTH),
  		    Bin(img1, affichage->format), tbb::auto_partitioner());
  t1 = tbb::tick_count::now();
  std::cout << "bin // : " << (t1 - t0).seconds() << "s" << std::endl;

  t0 = tbb::tick_count::now();
  tbb::parallel_for(tbb::blocked_range2d<int>(0,HEIGHT, 0,WIDTH),
  		    BinOr(img1, img2, affichage->format), tbb::auto_partitioner());
  t1 = tbb::tick_count::now();
  std::cout << "bin // : " << (t1 - t0).seconds() << "s" << std::endl;

  t0 = tbb::tick_count::now();
  tbb::parallel_for(tbb::blocked_range2d<int>(0,HEIGHT, 0,WIDTH),
  		    Convolution(img1, img2, mat, affichage->format), tbb::auto_partitioner());
  t1 = tbb::tick_count::now();
  std::cout << "convolution // : " << (t1 - t0).seconds() << "s" << std::endl;



  draw(img2, affichage);
  SDL_UpdateRect(affichage, 0, 0, 0, 0);




  //Waiting for the user to quit.
  do
    SDL_WaitEvent(&event);
  while (event.type != SDL_QUIT);
#endif

  shell::shell();

  SDL_Quit();
  return 0;
}
